package com.mainbo.modular.system.model.meta;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.mainbo.modular.system.model.PtConfig;
import com.mainbo.modular.system.model.meta.vo.Meta;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * @author moshang
 * @date 2020-02-25
 **/
public interface MetaProvider {
    /**
     * 获取所有的系统配置信息
     *
     * @return List
     */
    List<Meta> listAll();

    /**
     * 根据模型查询元数据，需注意code和type的设置 通过设置type可以查询到学校和区域的个性化的元数据
     *
     * @param model Config
     * @return List
     */
    List<Meta> listAll(PtConfig model);
    List<Meta> listAllNoOrg(PtConfig model);
    PtConfig listOne(EntityWrapper<PtConfig> model);
    /**
     * 根据id获取元数据信息
     *
     * @param id 主键id
     * @return Meta
     */
    Meta getMeta(Integer id);

    /**
     * 根据code 获取一条信息
     *
     * @param code 类型码
     * @return Meta
     */
    Meta getMeta(String code, String type);
    /**
     * 根据code 获取一条信息
     *
     * @param code 类型码
     * @return Meta
     */
    Meta getMeta(String code,String value, String type);

    /**
     * 根据学段获取系统配置信息
     *
     * @param phaseId 学段id
     * @return Config
     */
    PtConfig getSysConfigByPhaseId(Integer phaseId);

    /**
     * 根据code 和 type 获取信息
     *
     * @param code 类型码
     * @param type 类型
     * @return List
     */
    List<Meta> listMeta(String code, String type);

    List<Meta> listMeta(String code, String type, String orgId);

    @Component
    interface PhaseProvider extends MetaProvider {
        /**
         * 获取所有学段
         *
         * @return List
         */
        List<Meta> listAllPhase();
    }

    @Component
    interface PhaseSubjectProvider extends MetaProvider {
        /**
         * 根据id获取所有学科
         *
         * @param id 主键id
         * @return List
         */
        List<Meta> listAllSubject(Integer id);

        /**
         * 获取配置的所有学科
         *
         * @param orgId   不为null时查询学校配置的学科 为null时查询区域配置的学科
         * @param phaseId 学段id
         * @param areaId  区域id
         * @return List
         */
        List<Meta> listAllSubject(String orgId, Integer phaseId, Integer[] areaIds);

        /**
         * 根据学段获取系统配置的所有学科
         *
         * @param phaseId 学段id
         * @return List
         */
        List<Meta> listAllSubjectByPhaseId(Integer phaseId);

        /**
         * 获取全部学科信息
         *
         * @return List
         */
        List<Meta> listAllSubjectMeta();

        /**
         * 获取机构配置的学科配置信息
         *
         * @param orgId   机构id
         * @param phaseId 学段id
         * @return Config
         */
        PtConfig getConfigByOrg(String orgId, Integer phaseId);

        /**
         * 获取区域配置的学科配置信息
         *
         * @param areaId  区域id
         * @param phaseId 学段id
         * @return Config
         */
        PtConfig getConfigByArea(Integer areaId, Integer phaseId);

        /**
         * 根据学校id获取全部学科元数据--包括系统元数据和学校自定义的元数据和区域自定义元数据
         *
         * @param orgId   为null时，查询的是区域的数据
         * @param areaIds 区域id数组
         * @return List
         */
        List<Meta> listAllMeta(String orgId, Integer[] areaIds);

    }

    @Component
    interface PhaseGradeProvider extends MetaProvider {
        /**
         * 根据配置信息的id获取系统配置的所有年级
         *
         * @param id 主键id
         * @return List
         */
        List<Meta> listAllGrade(Integer id);

        /**
         * 根据学段获取系统配置的年级
         *
         * @param phaseId 学段id
         * @return List
         */
        List<Meta> listAllGradByPhaseId(Integer phaseId);

        /**
         * 根据学段获取系统配置的年级
         *
         * @param phaseId 学段id
         * @param code    区分系统年级和行政年级
         * @return List
         */
        List<Meta> listAllGradByPhaseIdAndCode(Integer phaseId, String code);

        /**
         * 获取全部年级
         *
         * @return List
         */
        List<Meta> listAllMeta();
    }

    @Component
    interface XZGradeProvider extends MetaProvider {
        /**
         * 根据配置信息的id获取系统配置的所有年级
         *
         * @param id 主键id
         * @return List
         */
        List<Meta> listAllGrade(Integer id);

        /**
         * 根据学段获取系统配置的年级
         *
         * @param phaseId 学段id
         * @return List
         */
        List<Meta> listAllGradByPhaseId(Integer phaseId);

        /**
         * 获取全部年级
         *
         * @return List
         */
        List<Meta> listAllMeta();
    }

    @Component
    interface OrgTypeProvider extends MetaProvider {
        /**
         * 根据学校类型id和学段获取年级
         *
         * @param id      学校类型id
         * @param phaseId 学段id
         * @return List
         */
        List<Meta> listAllGrade(Integer id, Integer phaseId);

        /**
         * 根据学校类型id获取该学校所有学段
         *
         * @param id 学校类型id
         * @return List
         */
        List<Meta> listAllPhase(Integer id);

        /**
         * 获取学校学段与年级对应关系
         *
         * @param id 元数据主键id
         * @return Map
         */
        Map<Integer, List<Meta>> listPhaseGradeMap(Integer id);

        /**
         * 获取学段对应行政年级的map
         *
         * @param id
         * @return Map
         */
        Map<Integer, List<Meta>> listPhaseXzGradeMap(Integer id);

        /**
         * 学校学段与行政年级数量对应关系
         *
         * @param
         * @return Map
         */
        Map<Integer, Integer> listPhaseXzGradeCountMap(Integer id);

    }

    @Component
    interface PublisherProvider extends MetaProvider {

        /**
         * 根据配置id获取出版社
         *
         * @param
         * @return List
         */
        List<Meta> listAllPublisher(Integer id);

        /**
         * 获取自定义配置的出版社
         *
         * @param phaseId   学段id
         * @param subjectId 学科id
         * @param orgId     不为null时查询学校配置的出版社 为null时查询区域配置的出版社
         * @return List
         */
        List<Meta> listAllPublisher(Integer phaseId, Integer subjectId,
                                    String orgId, Integer[] areaIds);

        /**
         * 根据学段和学科查询系统配置的出版社
         *
         * @param phaseId   学段id
         * @param subjectId 学科id
         * @return List
         */
        List<Meta> listAllByPhaseAndSubject(Integer phaseId, Integer subjectId);

        /**
         * 获取所有出版社元数据
         *
         * @return List
         */
        List<Meta> listAllPublisherMeta();

        /**
         * 获取系统出版社配置
         *
         * @return Config
         */
        PtConfig getPublishConfig(Integer phaseId, Integer subjectId);

        /**
         * 获取学校出版社配置信息
         *
         * @param phaseId   学段id
         * @param subjectId 学科id
         * @param orgId     机构id
         * @return Config
         */
        PtConfig getPublishConfig(Integer phaseId, Integer subjectId, String orgId);

        /**
         * 获取区域出版社配置信息
         *
         * @param phaseId   学段id
         * @param subjectId 学科id
         * @param areaId    机构id
         * @return Config
         */
        PtConfig getPublishConfig(Integer phaseId, Integer subjectId, Integer areaId);

        /**
         * 获取区域获取配置的出版社
         *
         * @param phaseId
         *          学段id
         * @param subjectId
         *          学科id
         * @param orgId
         *          机构id
         * @return List
         */
        // List<Meta> listAllPublisherByArea(Integer phaseId, Integer subjectId,
        // Integer[] areaIds);

        /**
         * 根据区域获取全部出版社元数据
         *
         * @param areaId
         *          区域id
         * @return List
         */
        // List<Meta> listAllPublisherMetaByArea(Integer[] areaIds);

        /**
         * 根据机构获取全部出版社元数据
         *
         * @param orgId   机构id
         * @param areaIds 机构所属区域id
         * @return List
         */
        List<Meta> listAllMeta(String orgId, Integer[] areaIds);
    }

    @Component
    interface SysConfigProvider extends MetaProvider {
        /**
         * 获取全部系统配置信息
         *
         * @return List
         */
        List<Meta> listAllConfig();

        /**
         * 根据配置name获取配置
         *
         * @return Meta
         */
        Meta getConfigByName(String code, String name);

        /**
         * 根据配置name获取配置
         *
         * @return Meta
         */
        Meta getConfigByCondition(String code, String name, PtConfig config);

        /**
         * 根据配置code和域名获取配置
         *
         * @return Meta
         */
        Meta getConfigByNameWithDomain(String code, String name, String domain);

        Meta getConfigByNameWithDomain(String code, String name, String domain, String orgId);
    }

    @Component
    interface BookEditionProvider extends MetaProvider {

        /**
         * 通过学科和学段获取系统配置的所有版本 参数不同组合查询不同条件下的版本 都不传，查询系统配置的全部版本
         * 如果三个参数都存在，则返回的列表只有一个元素。
         *
         * @param phaseId   学段
         * @param subjectId 学科
         * @param gradeId   年级
         * @return List
         */
        List<Meta> getALlEdition(Integer phaseId, Integer subjectId, Integer gradeId);

        /**
         * 获取学段，学科，年级配置的版本，三个参数都不为null，才能保证只查询出一条
         */
        PtConfig getEdition(Integer phaseId, Integer subjectId, Integer gradeId);

        /**
         * 查询学校配置的教材版本
         *
         * @param phaseId   学段id
         * @param subjectId 学科id
         * @param gradeId   年级id
         * @param orgId     机构id
         * @return List
         */
        List<Meta> getAllEditionWithSchool(Integer phaseId, Integer subjectId,
                                           Integer gradeId, String orgId);

        /**
         * 获取学段，学科，年级配置的版本，三个参数都不为null，才能保证只查询出一条
         *
         * @param phaseId   学段id
         * @param subjectId 学科id
         * @param gradeId   年级id
         * @param orgId     机构id
         * @return Meta
         */
        Meta getEditionWithSchool(Integer phaseId, Integer subjectId,
                                  Integer gradeId, String orgId);
    }

    @Component
    interface AppTypeProvider extends MetaProvider {
        /**
         * 获取所有应用类型
         *
         * @return List
         */
        List<Meta> getAllAppType();
    }

    @Component
    interface UnitTypeProvider extends MetaProvider {
        /**
         * 获取所有单位类型
         *
         * @return List
         */
        List<Meta> getAllUnitType();
    }

    @Component
    interface SchoolYearProvider extends MetaProvider {
        /**
         * 获取所有学年类型
         *
         * @return List
         */
        List<Meta> getAllSchoolYear();

        List<Meta> getSchoolYearWithOrg(String orgId);

        List<Meta> getSchoolYearWithOrgAndArea(String orgId);

        List<Meta> getSchoolYearWithArea(Integer areaId);

        List<Meta> getTerm(Integer schoolYearId);

        /**
         * 获取系统当前学年
         *
         * @return Integer
         */
        Integer getCurrentSchoolYear();

        /**
         * 获取系统当前学年
         *
         * @return Integer
         */
        Integer getCurrentSchoolYear(String orgId);

        /**
         * 获取系统当前学年
         *
         * @return Integer
         */
        Integer getCurrentSchoolYear(Integer areaId);

    }


}
